/**
 * File : Reactor.java <br/>
 * Author : alexgaoyh <br/>
 * Version : 1.1 <br/>
 * Date : 2017年7月5日 <br/>
 * Modify : <br/>
 * Package Name : com.MutiModule.common.codeing.reactor <br/>
 * Project Name : MutiModule-common <br/>
 * Description : <br/>
 * 
 */

package com.MutiModule.common.codeing.nio.reactor;

import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ClassName : Reactor <br/>
 * Function : TODO ADD FUNCTION. <br/>
 * Reason : TODO ADD REASON. <br/>
 * Date : 2017年7月5日 下午1:34:43 <br/>
 * 
 * @author : alexgaoyh <br/>
 * @version : 1.1 <br/>
 * @since : JDK 1.6 <br/>
 * @see
 */

public class Reactor {
	private Map<Integer, EventHandler> registeredHandlers = new ConcurrentHashMap<Integer, EventHandler>();
	private Selector demultiplexer;

	public Reactor() throws Exception {
		demultiplexer = Selector.open();
	}

	public Selector getDemultiplexer() {
		return demultiplexer;
	}

	public void registerEventHandler(int eventType, EventHandler eventHandler) {
		registeredHandlers.put(eventType, eventHandler);
	}

	public void registerChannel(int eventType, SelectableChannel channel) throws Exception {
		channel.register(demultiplexer, eventType);
	}

	public void run() {
		try {
			while (true) { // Loop indefinitely
				demultiplexer.select();

				Set<SelectionKey> readyHandles = demultiplexer.selectedKeys();
				Iterator<SelectionKey> handleIterator = readyHandles.iterator();

				while (handleIterator.hasNext()) {
					SelectionKey handle = handleIterator.next();

					if (handle.isAcceptable()) {
						EventHandler handler = registeredHandlers.get(SelectionKey.OP_ACCEPT);
						handler.handleEvent(handle);
					}

					if (handle.isReadable()) {
						EventHandler handler = registeredHandlers.get(SelectionKey.OP_READ);
						handler.handleEvent(handle);
						handleIterator.remove();
					}

					if (handle.isWritable()) {
						EventHandler handler = registeredHandlers.get(SelectionKey.OP_WRITE);
						handler.handleEvent(handle);
						handleIterator.remove();
					}
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}

	}

}
